﻿using System;
using System.Windows.Forms;
using FluentParser.Editor.Grammars;
using FluentParser.Expressions;

namespace FluentParser.Editor
{
    public partial class Form1 : Form
    {
        private Colorizer _colorizer;

        public Form1()
        {
            InitializeComponent();
            _colorizer = new Colorizer(txtInput);
            txtInput.Text = "1 + 2 * 3"; //File.ReadAllText(@"C:\Users\Zumten\Desktop\TextCompiler\TextCompiler.Host\bin\Debug\test.ini");
        }

        private void btnParse_Click(object sender, EventArgs e)
        {
            Grammar grammar = new AddNumbersGrammar();
            GrammarContext context = new GrammarContext(txtInput.Text) {AllowToRecover = true};
            ParsingNodeResult node = grammar.ParseTree(context);
            _colorizer.Apply(node);

            _gridErrors.Rows.Clear();
            
            foreach (ParsingException error in context.Errors)
                _gridErrors.Rows.Add(error.Start, error.End, error.Message);

            ProcessNode(treeView1.Nodes, node);
        }

        private static void ProcessNode(TreeNodeCollection parentUiCollection, ParsingNodeResult parsingNode)
        {
            string name = String.Format("{0} ({1} to {2})", parsingNode.Expression.TypeOperation, parsingNode.Index, parsingNode.End);
            TreeNode uiNode = parentUiCollection.Add(name);
            uiNode.ImageIndex = GetIconIndex(parsingNode);
            uiNode.SelectedImageIndex = uiNode.ImageIndex;
            uiNode.Tag = parsingNode;

            switch (parsingNode.Expression.TypeOperation)
            {
                case OperationType.Grouping:
                    ProcessGroupingNode(uiNode.Nodes, parsingNode);
                    break;

                case OperationType.Parsing:

                    string customText = String.Concat(parsingNode.Value);
                    if (customText.Length > 15)
                        customText = customText.Substring(0, 12) + "...";
                    uiNode.Text = String.Format("\"{0}\" ({1} to {2})", customText, parsingNode.Index, parsingNode.End);
                    break;
            }

            if (parsingNode.Expression.TypeOperation != OperationType.Grouping)
            {
                foreach (ParsingNodeResult childNode in parsingNode.Nodes)
                    ProcessNode(uiNode.Nodes, childNode);
            }
        }

        private static void ProcessGroupingNode(TreeNodeCollection parentUiCollection, ParsingNodeResult parsingNode)
        {
            foreach (ParsingNodeResult childNode in parsingNode.Nodes)
            {
                if (childNode.Expression.TypeOperation == OperationType.Grouping)
                    ProcessGroupingNode(parentUiCollection, childNode);
                else
                    ProcessNode(parentUiCollection, childNode);
            }
        }

        private static int GetIconIndex(ParsingNodeResult parsingNode)
        {
            if (parsingNode.Error != null)
            {
                switch(parsingNode.Error.TypeException)
                {
                    case ParsingExceptionType.Warning: return 2;
                    case ParsingExceptionType.Error: return 3;
                    case ParsingExceptionType.FatalError: return 4;
                }
            }

            return (parsingNode.IsSuccess ? 0 : 1);
        }

        private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
        {
            ParsingNodeResult node = treeView1.SelectedNode.Tag as ParsingNodeResult;
            if (node != null)
            {
                txtInput.Select(node.Index, node.Length);
                propertyGrid1.SelectedObject = node.Value;
            }
        }

        private void splitContainer1_Panel1_Paint(object sender, PaintEventArgs e)
        {

        }
    }
}
